package com.login.resdk.resdk;

import jakarta.servlet.http.HttpSession;
import jakarta.servlet.http.HttpSessionEvent;
import jakarta.servlet.http.HttpSessionListener;
import org.springframework.stereotype.Component;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * HttpSession 对象管理器（示例实现）
 * 
 * <p><b>注意：此实现仅用于演示目的，实际生产环境应考虑以下问题：</b>
 * <ul>
 *   <li>使用 {@link ConcurrentHashMap} 替代 {@link ArrayList} 以避免并发问题</li>
 *   <li>考虑使用弱引用防止内存泄漏</li>
 *   <li>分布式环境下应改用集中式会话存储（如Redis）</li>
 *   <li>实际项目建议直接使用Spring Session等成熟方案</li>
 * </ul>
 * 
 * @author click33
 * @since 2022-04-30
 */
@Component
public class HttpSessionManager implements HttpSessionListener {
    
    /**
     * 使用线程安全的Map存储会话，key为sessionId，value为弱引用包装的session
     */
    private static final ConcurrentMap<String, WeakReference<HttpSession>> SESSION_MAP =
        new ConcurrentHashMap<>(128);

    /**
     * 获取当前活跃会话数量
     */
    public static int getActiveSessionCount() {
        return SESSION_MAP.size();
    }

    /**
     * 获取所有活跃会话的ID集合（快照视图）
     */
    public static Set<String> getActiveSessionIds() {
        return Collections.unmodifiableSet(SESSION_MAP.keySet());
    }
    /**
     * 获取所有活跃会话的不可修改视图
     *
     * <p><b>注意：返回的集合是会话快照，可能包含已被销毁的会话引用</b>
     *
     * @return 包含所有活跃HttpSession的不可修改集合
     */
    public static Set<HttpSession> getAllSessions() {
        Set<HttpSession> activeSessions = new HashSet<>(SESSION_MAP.size());

        // 遍历并筛选有效会话
        for (WeakReference<HttpSession> ref : SESSION_MAP.values()) {
            HttpSession session = ref.get();
            if (session != null) {
                try {
                    // 验证会话是否仍然有效
                    session.getLastAccessedTime();
                    activeSessions.add(session);
                } catch (IllegalStateException e) {
                    // 会话已失效则跳过
                }
            }
        }

        return Collections.unmodifiableSet(activeSessions);
    }
    @Override
    public void sessionCreated(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        SESSION_MAP.put(session.getId(), new WeakReference<>(session));
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        HttpSession session = event.getSession();
        SESSION_MAP.remove(session.getId());
        
        // 显式清理资源（防御性编程）
        try {
            session.invalidate();
        } catch (IllegalStateException e) {
            // 会话已失效的情况忽略
        }
    }
}